﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Company.Core.Helpers;
using Company.Core.Logger;
using Company.Shell.Interfaces;
using Company.Shell.Models;
using Company.Shell.Services;
using LiveCharts;
using LiveCharts.Defaults;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Windows.Input;


namespace Company.Shell.ViewModels
{
    public class HistoryViewModel : ObservableObject
    {


        private ObservableCollection<FileInfo> files = [];
        /// <summary>
        /// 所有曲线文件
        /// </summary>
        public ObservableCollection<FileInfo> Files
        {
            get { return files; }
            set { SetProperty(ref files, value); }
        }

        private FileInfo? fileInfo;
        /// <summary>
        /// 当前历史文件
        /// </summary>
        public FileInfo? FileInfo
        {
            get { return fileInfo; }
            set { SetProperty(ref fileInfo, value); }
        }
        public ICommand? SelectFileCommand { get; }
        public ICommand? LoadedCommand { get; }

        public ICommand? SelectRoomCommand { get; }
        public IRoomManager RoomManager { get; }
        public ProgramManager ProgramManager { get; }
        public HistoryViewModel(IRoomManager roomManager, ProgramManager programManager)
        {
            RoomManager = roomManager;
            ProgramManager = programManager;
            SelectFileCommand = new AsyncRelayCommand(OnSelectFileCommand);
            LoadedCommand = new AsyncRelayCommand(OnLoadedCommand);
            SelectRoomCommand = new AsyncRelayCommand(OnSelectRoomCommand);
        }
        /// <summary>
        /// 切换房间时，重新加载文件列表
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private async Task OnSelectRoomCommand()
        {
            if (RoomManager.CurrentRoom != null)
            {
                Files = await InitializeFiles(RoomManager.CurrentRoom);
            }
        }

        private async Task OnLoadedCommand()
        {
            if(RoomManager.CurrentRoom != null)
            {
                Files = await InitializeFiles(RoomManager.CurrentRoom);
            }
        }
        /// <summary>
        /// 加载当前房间的所有历史文件
        /// </summary>
        /// <param name="currentRoom"></param>
        /// <returns></returns>

        private async Task<ObservableCollection<FileInfo>> InitializeFiles(RoomEntity currentRoom)
        {
            return await Task.Run(() =>
            {
                ObservableCollection<FileInfo> files = [];
                try
                {
                   var folder = CurveHelper.GetCurveFolder(DateTime.Now.Year);
                   DirectoryInfo dir = new(folder);
                   if (!dir.Exists) return files;
                   var filesInDir = dir.GetFiles().Where(file => file.Name.EndsWith(".csv")).ToList();
                   foreach (var file in filesInDir)
                   {
                       var parts = file.Name.Split('_', '.');
                        // 查找格式为 Room_{currentRoomId}_ 开头的文件
                        if (parts.Length > 0 && int.TryParse(parts[1], out int roomId) && roomId == currentRoom.Id)
                           files.Add(file);
                   }
                }
                catch (Exception ex)
                {
                    Logs.Error(ex);
                }
                return files;
            });
        }

        private async Task OnSelectFileCommand()
        {
            if (FileInfo == null) return;
            await InitializeCurve(FileInfo);
        }
        /// <summary>
        ///加载曲线数据
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private async Task InitializeCurve(FileInfo file)
        {
            // 使用反射获取所有 Line 属性
            var lineProperties = this.GetType()
                .GetProperties()
                .Where(p => p.Name.StartsWith("Line") && p.PropertyType == typeof(ChartValues<ObservablePoint>))
                .OrderBy(p => {
                    var numberPart = p.Name.Substring(4); // 移除 "Line" 前缀
                    return int.TryParse(numberPart, out int number) ? number : int.MaxValue;
                })
                .ToArray();
            if (file == null) return;
            if(!File.Exists(file.FullName)) return;
            await Task.Run(() => 
            {
                System.Windows.Application.Current.Dispatcher.Invoke (() => {
                    // 使用缓存的反射结果清空所有 Line
                    foreach (var property in lineProperties)
                    {
                        var chartValues = property.GetValue(this) as ChartValues<ObservablePoint>;
                        chartValues?.Clear();
                    }
                });
                //读取csv文件
                List<string> rows = [.. File.ReadAllLines(file.FullName, Encoding.UTF8)];
                if(rows == null || rows.Count == 0) return;
                rows.RemoveAt(0);//移除标题行

                try
                {
                    
                    foreach (var row in rows)
                    {
                        string[] colums = row.Split(',');
                        if (colums == null || colums.Length == 0) continue;
                        var success = double.TryParse(colums[1], out double x);
                        if (!success) continue;

                        System.Windows.Application.Current.Dispatcher.Invoke(() =>
                        {
                            for (int i = 0; i < lineProperties.Length && i + 2 < colums.Length; i++)
                            {
                                if (double.TryParse(colums[i + 2], out double y))
                                {
                                    var point = new ObservablePoint(x, y);
                                    var chartValues = lineProperties[i].GetValue(this) as ChartValues<ObservablePoint>;
                                    chartValues?.Add(point);
                                }
                            }
                        });
                    }
                }
                catch (Exception ex)
                {
                    Logs.Error(ex);
                }
            });
        }



        #region 12个数字量的曲线
        private ChartValues<ObservablePoint> line0 = new();
        public ChartValues<ObservablePoint> Line0
        {
            get => line0;
            set => SetProperty(ref line0, value);
        }

        private ChartValues<ObservablePoint> line1 = new();
        public ChartValues<ObservablePoint> Line1
        {
            get => line1;
            set => SetProperty(ref line1, value);
        }

        private ChartValues<ObservablePoint> line2 = new();
        public ChartValues<ObservablePoint> Line2
        {
            get => line2;
            set => SetProperty(ref line2, value);
        }

        private ChartValues<ObservablePoint> line3 = new();
        public ChartValues<ObservablePoint> Line3
        {
            get => line3;
            set => SetProperty(ref line3, value);
        }

        private ChartValues<ObservablePoint> line4 = new();
        public ChartValues<ObservablePoint> Line4
        {
            get => line4;
            set => SetProperty(ref line4, value);
        }

        private ChartValues<ObservablePoint> line5 = new();
        public ChartValues<ObservablePoint> Line5
        {
            get => line5;
            set => SetProperty(ref line5, value);
        }

        private ChartValues<ObservablePoint> line6 = new();
        public ChartValues<ObservablePoint> Line6
        {
            get => line6;
            set => SetProperty(ref line6, value);
        }

        private ChartValues<ObservablePoint> line7 = new();
        public ChartValues<ObservablePoint> Line7
        {
            get => line7;
            set => SetProperty(ref line7, value);
        }

        private ChartValues<ObservablePoint> line8 = new();
        public ChartValues<ObservablePoint> Line8
        {
            get => line8;
            set => SetProperty(ref line8, value);
        }

        private ChartValues<ObservablePoint> line9 = new();
        public ChartValues<ObservablePoint> Line9
        {
            get => line9;
            set => SetProperty(ref line9, value);
        }

        private ChartValues<ObservablePoint> line10 = new();
        public ChartValues<ObservablePoint> Line10
        {
            get => line10;
            set => SetProperty(ref line10, value);
        }

        private ChartValues<ObservablePoint> line11 = new();
        public ChartValues<ObservablePoint> Line11
        {
            get => line11;
            set => SetProperty(ref line11, value);
        }
        #endregion
    }
}
